home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Sounds Terrific 2
/
Sounds Terrific II (1996)(Weird Science)(Disc 1 of 2)[Amiga-PC].iso
/
archives
/
amiga
/
tracker_4_31.lzh
/
tracker
/
lookup.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-21
|
6KB
|
257 lines
/* lookup.c
vi:ts=3 sw=3:
*/
/* A simple database lookup.
* every entry in the database files is of the form: initial string value
* We just have to match the initial string, no separators required.
* Not that the specification just asks for a matching entry, not
* necessarily the first or the last.
*/
/* $Id: lookup.c,v 4.11 1995/02/21 17:54:32 espie Exp $ */
/* $Log: lookup.c,v $
* Revision 4.11 1995/02/21 17:54:32 espie
* Internal problem: buggy RCS. Fixed logs.
*
* Revision 4.10 1995/02/21 16:53:24 espie
* *** empty log message ***
*
* Revision 4.5 1995/02/01 16:39:04 espie
* Moved includes to defs.h
*
* Revision 1.2 1992/07/22 14:50:25 espie
* open_file changed, so lookup had to change to incorporate paths as well.
*/
#include "defs.h"
#include "extern.h"
ID("$Id: lookup.c,v 4.11 1995/02/21 17:54:32 espie Exp $")
/* the lookup structure is PRIVATE */
#define HANDLE 0 /* a null type, for memory handling */
#define FNAME 1 /* a filename, which has not yet been opened */
#define FOPENED 2 /* a file, once opened */
#define STRING 3 /* an already accounted for string */
struct lookup
{
int type;
union
{
char *filename;
FILE *file;
char *string;
char *path;
} value;
struct lookup *next;
};
/***
*
* lookup memory handling
*
***/
/* link_lookup(base, new): link a new element inside the existing chain */
LOCAL void link_lookup(handle, new)
struct lookup *handle, *new;
{
new->next = handle->next;
handle->next = new;
}
LOCAL void set_lookup(handle, path)
struct lookup *handle;
char *path;
{
handle->type = HANDLE;
handle->value.path = path;
}
/* new = create_lookup(): create an empty element,
* chain anchor or to be filled
*/
struct lookup *create_lookup(path)
char *path;
{
struct lookup *new;
new = (struct lookup *)malloc(sizeof(struct lookup));
if (!new)
exit(10);
set_lookup(path);
new->next = NULL;
return new;
}
/* free_lookup(handle): free the whole chain. Note that filenames
* do not belong to us
*/
void free_lookup(handle)
struct lookup *handle;
{
struct lookup *to_free;
while(handle)
{
to_free = handle;
handle = handle->next;
switch(to_free->type)
{
case HANDLE:
case FNAME: /* filenames don't belong to you */
break;
case FOPENED:
close_file(to_free->value.file.fhandle,
to_free->value.file.filetype);
break;
case STRING:
free(to_free->value.string);
break;
}
free(to_free);
}
}
/* add_lookup(handle, filename): add a new potential filename to the lookup
* handle
*/
void add_lookup(handle, filename)
struct lookup *handle;
char *filename;
{
struct lookup *new;
new = create_lookup();
new->type = FNAME;
new->value.filename = filename;
link_lookup(handle, new);
}
/* postfix = check_prefix(template, s):
* if s is a prefix of template, return the remaining part of template,
* else return NULL.
* Note difference between NULL result and empty postfix (pointer to NULL)
*/
static char *check_prefix(template, s)
char *template;
char *s;
{
for (; *s; template++, s++)
/* *s != 0 at that point */
if (*template != *s)
return NULL;
while(*template == ' ' || *template == '\t')
template++;
return template;
}
/* copy = create_copy(s): allocate memory and create a copy of string s.
* get rid of spurious \n at the end.
*/
static char *create_copy(s)
char *s;
{
char *new;
int len;
len = strlen(s);
while(s[len - 1] == '\n')
s[--len] = 0;
new = malloc(len + 1);
if (!new)
exit(10);
return strcpy(new, s);
}
#define BUFSIZE 1500
LOCAL char *internal_lookup();
/* postfix = lookup(handle, s): lookup string s in the database indexed by
* handle.
*/
char *lookup(handle, s)
struct lookup *handle;
char *s;
{
/* the internal handler also maintains a current path */
return internal_lookup(handle, s, NULL);
}
LOCAL char *internal_lookup(handle, s, path)
struct lookup *handle;
char *s;
char *path;
{
char *r;
static char buffer[BUFSIZE];
struct lookup *new;
if (handle)
{
switch(handle->type)
{
case STRING:
r = check_string(handle->value.string, s);
if (r)
return r;
else
return internal_lookup(handle->next, s, path);
case HANDLE:
return internal_lookup(handle->next, s,
handle->value.path ? handle->value.path : path);
case FNAME:
r = internal_lookup(handle->next, s, path);
if (r)
return r;
else
{
if (handle->value.file =
open_file(handle->value.filename, "r", path))
{
handle->type = FOPENED;
return internal_lookup(handle, s, path);
}
else
{
set_lookup(handle, NULL);
return NULL;
}
}
case FOPENED:
r = internal_lookup(handle->next, s, path);
if (r)
return r;
else
{
if (fgets(buffer, BUFSIZE, handle->value.file))
{
new = create_lookup(NULL);
new->type = STRING;
new->value.string = create_copy(buffer);
link_lookup(handle, new);
r = check_prefix(new->value.string, s);
if (r)
return r;
else
return internal_lookup(handle, s, path);
}
else
{
close_file(handle->value.file);
set_lookup(new, NULL);
}
}
}
}
else
return NULL;
}